Detecting spikes and pass-filters</H2>


In [1]:
%pylab inline
from scipy.signal import find_peaks
from scipy.signal import butter, lfilter


Populating the interactive namespace from numpy and matplotlib

In [2]:
# load data
voltage = np.load('./data/2019-06-06CM_ch25.npy') # voltage in microVolts, raw signal
sf = 30000 # sampling frequency (in Hz)
dt = 1/sf # sampling interval (sec)
time = np.linspace(start =0, stop = voltage.size*dt, num = voltage.size )

In [4]:
fig = plt.figure(figsize=(12,4))
plt.plot(time, voltage, lw=.5)
plt.xlabel('Time (sec)'), plt.ylabel('Voltage ($\mu$V)');
plt.ylim(-60,60);


Finding spikes in the raw signal


In [5]:
fig = plt.figure(figsize=(12,4))
plt.plot(time, voltage, lw=.5)
plt.xlabel('Time (sec)'), plt.ylabel('Voltage ($\mu$V)');
x, y = find_peaks(voltage*-1, height=20)
plt.ylim(-60,60);
plt.plot(x*dt,np.ones(x.size)*30, 'o')


Out[5]:
[<matplotlib.lines.Line2D at 0x7f0227446cf8>]

Calculate sampling interval in ms


In [6]:
# take 2 ms spikes 2/dt 
dt_ms =dt*1000 # transform sampling into ms
print(2/dt_ms)


60.0

In [7]:
#peak-align spikes
tmax = 5

ms = np.linspace(start=0, stop=tmax, num=tmax/dt_ms)

avg = list()
for peak in x:
    spk = voltage[peak - int((tmax/2)/dt_ms):peak + int((tmax/2)/dt_ms)]
    plt.plot(ms, spk, color='gray', lw=1)
    avg.append(spk)

avg1 = np.mean(avg,axis=0)
plt.plot(ms, avg1, color='black', lw=2);
plt.ylabel('Voltage ($/mu$V)'), plt.xlabel('Time (ms)');


/home/segundo.martinez/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:4: DeprecationWarning: object of type <class 'float'> cannot be safely interpreted as an integer.
  after removing the cwd from sys.path.

Band-pass filtering the signal


In [8]:
def bandpass_filter(data, low, high):
    """
    Perform a band-pass filter of the data with a second-order
    Butter 
    """
    nyq = sf/2 # Nysquid is 15 kHz
    
    low_band = low/nyq
    high_band = high/nyq
    
    # calculate the coefficients
    b, a = butter(N=2, Wn = [low_band, high_band], btype = 'band')
    # filter signal
    filtered_data = lfilter(b, a, data)
    
    return filtered_data

In [9]:
f_voltage = bandpass_filter(data = voltage, low = 300, high = 6000)

Finding spikes in the filtered signal


In [10]:
fig = plt.figure(figsize=(12,4))
plt.plot(time, f_voltage, lw=.5)
plt.xlabel('Time (sec)'), plt.ylabel('Voltage ($\mu$V)');
x, y = find_peaks(f_voltage*-1, height=20)
plt.ylim(-60,60);
plt.plot(x*dt,np.ones(x.size)*40, 'o')


Out[10]:
[<matplotlib.lines.Line2D at 0x7f0227301b70>]

In [11]:
#peak-align spikes
tmax = 5

ms = np.linspace(start=0, stop=tmax, num=tmax/dt_ms)

avg = list()
for peak in x:
    spk = f_voltage[peak - int((tmax/2)/dt_ms):peak + int((tmax/2)/dt_ms)]
    plt.plot(ms, spk, color='gray', lw=1)
    avg.append(spk)

avg2 = np.mean(avg,axis=0)
plt.plot(ms, avg2, color='darkblue', lw=2);
plt.ylabel('Voltage ($/mu$V)'), plt.xlabel('Time (ms)');


/home/segundo.martinez/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:4: DeprecationWarning: object of type <class 'float'> cannot be safely interpreted as an integer.
  after removing the cwd from sys.path.

Compare spike averages


In [12]:
plt.plot(ms, avg1, color='black', lw =2, label='raw')
plt.plot(ms, avg2, color='darkblue', lw=2, label='0.3/6k Hz');
plt.ylabel('Voltage ($/mu$V)'), plt.xlabel('Time (ms)');
plt.legend()


Out[12]:
<matplotlib.legend.Legend at 0x7f0227296c88>

In [ ]: